﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace GArphics
{
    public class RenderEngine2D : RenderEngine
    {
        public override void Render(RenderData Data)
        {
            Bitmap oNewBitmap = null;

            if (Data.Tree != null && Data.Size != null)
            {
                if (Data.CalculateFitness)
                {
                    Data.Tree.Fitness = 0;
                }

                oNewBitmap = new Bitmap(Data.Size.Width, Data.Size.Height);

                double dXmin = Data.Tree.Xmin;
                double dXmax = Data.Tree.Xmax;
                double dYmin = Data.Tree.Ymin;
                double dYmax = Data.Tree.Ymax;

                int iX = 0;
                int iY = 0;
                int iWidth = Data.Size.Width;
                int iHeight = Data.Size.Height;

                double dXStep = (dXmax - dXmin) / iWidth;
                double dYStep = (dYmax - dYmin) / iHeight;
                double dX = dXmin;
                double dY = dYmin;

                oNewBitmap = new Bitmap(iWidth, iHeight);

                double[,] dValues = new double[iWidth, iHeight];

                for (iX = 0; iX < iWidth; iX++)
                {
                    dY = dYmin;

                    for (iY = iHeight - 1; iY >= 0; iY--)
                    {
                        dY += dYStep;
                        dValues[iX, iY] = Data.Tree.GetValue(dX, dY);
                    }

                    dX += dXStep;
                }

                double dMin = double.MaxValue;
                double dMax = double.MinValue;

                for (iX = 0; iX < iWidth; iX++)
                {
                    for (iY = 0; iY < iHeight; iY++)
                    {
                        if (dValues[iX, iY] > dMax)
                            dMax = dValues[iX, iY];
                        if (dValues[iX, iY] < dMin)
                            dMin = dValues[iX, iY];
                    }
                }

                double dGap = dMax - dMin;


                for (iX = 0; iX < iWidth; iX++)
                {
                    for (iY = 0; iY < iHeight; iY++)
                    {
                        double dColorValue = (dValues[iX, iY] - dMin) / dGap * 16777215;
                        int iColorValue = 0;

                        if (dColorValue >= int.MaxValue)
                        {
                            iColorValue = int.MaxValue;
                        }
                        else if (dColorValue <= int.MinValue)
                        {
                            iColorValue = int.MinValue;
                        }
                        else if (!double.IsNaN(dColorValue))
                        {
                            try
                            {
                                iColorValue = Convert.ToInt32(dColorValue);
                            }
                            catch (Exception) { }
                        }

                        int iRed = iColorValue & 0xFF;
                        int iGreen = (iColorValue & 0xFF00) >> 8;
                        int iBlue = (iColorValue & 0xFF0000) >> 16;

                        if (Data.Tree.RedChannelModifier)
                            iRed = Data.Tree.RedChannelValue;
                        if (Data.Tree.GreenChannelModifier)
                            iGreen = Data.Tree.GreenChannelValue;
                        if (Data.Tree.BlueChannelModifier)
                            iBlue = Data.Tree.BlueChannelValue;

                        if (Data.CalculateFitness)
                        {
                            /*Data.Tree.Fitness += Math.Abs(oTargetImage.GetPixel(iX, iY).R - iRed);
                            Data.Tree.Fitness += Math.Abs(oTargetImage.GetPixel(iX, iY).G - iGreen);
                            Data.Tree.Fitness += Math.Abs(oTargetImage.GetPixel(iX, iY).B - iBlue);*/
                        }

                        oNewBitmap.SetPixel(iX, iY, Color.FromArgb(iRed, iGreen, iBlue));
                    }
                }
            }

            Data.Image = oNewBitmap;
        }
    }
}
